package com.basic.backend.utils;


import com.basic.backend.common.ErrorCode;
import com.basic.backend.exception.BusinessException;
import com.basic.backend.model.dto.captcha.CaptchaInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Component
public class CaptchaValidator {

    private final RedisTemplate<String, Object> redisTemplate;

    // 通过构造器注入
    @Autowired
    public CaptchaValidator(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }



    public void validateCaptcha(HttpServletRequest request, String inputCode) {
        String clientIP = NetworkUtils.getClientRealIP(request);
        String redisKey = "CAPTCHA:" + clientIP;

        if (redisTemplate == null) {
            throw new IllegalStateException("RedisTemplate is not initialized");
        }
        CaptchaInfo captchaInfo = (CaptchaInfo) redisTemplate.opsForValue().get(redisKey);

        // 1. 检查验证码是否存在
        if (captchaInfo == null) {
            throw new BusinessException(ErrorCode.CAPTCHA_EXPIRED, "请先获取验证码");
        }

        // 2. 检查是否过期
        if (System.currentTimeMillis() > captchaInfo.getExpireTime()) {
            redisTemplate.delete(redisKey);
            throw new BusinessException(ErrorCode.CAPTCHA_EXPIRED);
        }

        // 3. 检查尝试次数
        if (captchaInfo.getTryCount() >= 3) {
            redisTemplate.delete(redisKey);
            throw new BusinessException(ErrorCode.CAPTCHA_TRY_LIMIT);
        }

        // 4. 验证码内容校验
        if (!captchaInfo.getCode().equalsIgnoreCase(inputCode)) {
            // 更新尝试次数
            captchaInfo.setTryCount(captchaInfo.getTryCount() + 1);
            redisTemplate.opsForValue().set(redisKey, captchaInfo, 5, TimeUnit.MINUTES);
            throw new BusinessException(ErrorCode.CAPTCHA_ERROR);
        }

        // 5. 验证通过删除Key
        redisTemplate.delete(redisKey);
    }
}